#ifndef __LOCK_H__
#define __LOCK_H__

#define FERR_LOCK   1
#define MUTEX_LOCK  0
#define ATOMIC_LOCK 2
#define NO_LOCK    -1

#ifndef USE_LOCK_TYPE
#define USE_LOCK_TYPE FERR_LOCK
#endif

#if (USE_LOCK_TYPE == ATOMIC_LOCK)
    #include <stdatomic.h>
    
    #define LOCK_DEFINE(v)          atomic_flag v
    #define LOCK_INIT(lock, val)    atomic_flag_clear(&lock)
    #define LOCK(lock)              while (atomic_flag_test_and_set(&lock)) sleep(0);atomic_thread_fence(memory_order_acquire)
    #define UNLOCK(lock)            atomic_thread_fence(memory_order_release);atomic_flag_clear(&lock)
    #define TRY_LOCK(lock)          
    #define DESTROY_LOCK(lock)
  
    #define RW_LOCK_INIT(lock,v)    atomic_flag_clear(&lock##_r);atomic_flag_clear(&lock##_w)
    #define RW_R_LOCK(lock)         LOCK(lock##_r)
    #define RW_W_LOCK(lock)         LOCK(lock##_w)
    #define RW_R_UNLOCK(lock)       UNLOCK(lock##_r)
    #define RW_W_UNLOCK(lock)       UNLOCK(lock##_w)
    #define RW_LOCK_DEFINE(lock)    atomic_flag lock##_r;atomic_flag lock##_w
    
#elif(USE_LOCK_TYPE == FERR_LOCK)
    
    #define CAS(lock)               __sync_bool_compare_and_swap (&(lock), 0, 1)

    #define LOCK_DEFINE(v)          volatile unsigned int v
    #define LOCK_INIT(lock, val)    lock = val
    #define LOCK(lock)              while(!CAS(lock)) sleep(0)
    #define UNLOCK(lock)            __sync_lock_release(&(lock))
    #define TRY_LOCK(lock)          CAS(lock)?0:1
    #define DESTROY_LOCK(lock)
  
    #define RW_LOCK_INIT(lock,v)    lock##_r=v;lock##_w=v
    #define RW_R_LOCK(lock)         LOCK(lock##_r)
    #define RW_W_LOCK(lock)         LOCK(lock##_w)
    #define RW_R_UNLOCK(lock)       UNLOCK(lock##_r)
    #define RW_W_UNLOCK(lock)       UNLOCK(lock##_w)
    #define RW_LOCK_DEFINE(lock)    volatile unsigned int lock##_r;volatile unsigned int lock##_w
    
#elif(USE_LOCK_TYPE == MUTEX_LOCK)
    //#pragma message "system USE_LOCK_TYPE -> MUTEX_LOCK"
    #include <pthread.h>//头文件
   /*
    * int pthread_mutex_lock(pthread_mutex_t *mutex,)
    * int pthread_mutex_trylock(pthread_mutex_t *mutex,)
    * int pthread_mutex_unlock(pthread_mutex_t *mutex,)
    * int pthread_mutex_destroy(pthread_mutex_t *mutex,)
    */
    #define LOCK_DEFINE(v)          pthread_mutex_t v
    #define LOCK_INIT(lock,val)     pthread_mutex_init(&(lock),val)
    #define LOCK(lock)              pthread_mutex_lock(&(lock))
    #define UNLOCK(lock)            pthread_mutex_unlock(&(lock))
    #define TRY_LOCK(lock)          pthread_mutex_trylock(&(lock))
    #define DESTROY_LOCK(lock)      pthread_mutex_destroy(&(lock))
   /*
    *int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);//加读阻塞锁
    *int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);//加写阻塞锁
    *int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);//解锁
    *
    *int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);//加读非阻塞锁
    *int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);//加写非阻塞锁
    */
    #define RW_LOCK_DEFINE(lock)    pthread_rwlock_t lock
    #define RW_LOCK_INIT(lock,val)  pthread_rwlock_init(&(lock),val)
    #define RW_R_LOCK(lock)         pthread_rwlock_rdlock(&(lock))
    #define RW_W_LOCK(lock)         pthread_rwlock_wrlock(&(lock))
    #define RW_R_UNLOCK(lock)       pthread_rwlock_unlock(&(lock))
    #define RW_W_UNLOCK(lock)       pthread_rwlock_unlock(&(lock))
    #define RW_R_TRY_LOCK(lock)     pthread_rwlock_tryrdlock(&(lock))
    #define RW_W_TRY_LOCK(lock)     pthread_rwlock_trywrlock(&(lock))
#else
    //#pragma message "system USE_LOCK_TYPE -> NO_LOCK"
    #define LOCK_DEFINE(v)       
    #define LOCK_INIT(lock, val) 
    #define LOCK(lock)           
    #define UNLOCK(lock)         
    #define TRY_LOCK(lock)        
    #define DESTROY_LOCK(lock) 

    #define RW_LOCK_INIT(lock,v) 
    #define RW_R_LOCK(lock)      
    #define RW_W_LOCK(lock)      
    #define RW_R_UNLOCK(lock)    
    #define RW_W_UNLOCK(lock)    
    #define RW_LOCK_DEFINE(lock) 
#endif

#endif
